const path = require("path")
const { smart } = require("webpack-merge")
const webpack = require("webpack")
const { srcPath, distPath } = require("./paths")
const webpackCommonConf = require("./webpack.common.js")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const TerserJSPlugin = require('terser-webpack-plugin')
const HappyPack = require('happypack')
const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')


module.exports = smart(webpackCommonConf, {
  // production 之前说过，如果mdoe是production，会自动压缩js
  // 但是如果你压缩了css，就不会再自动压缩js，需要手动配置
  mode: "production",  // 指定生产模式打包
  output: {
    filename: '[name].[contentHash:8].js', // 打包后的文件叫bundle.js
    path: distPath, // 打包后的文件放在哪里
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        // loader: ["babel-loader"],
        // 把对.js文件的处理转交给id为babel的HappyPack实例
        use: ['happypack/loader?id=babel'],
        include: srcPath,
        // exclude: /node_modules/
      },
      {
        test: /\.(png|jpg|jpeg|gif)$/,
        use: {
          loader: "url-loader",
          options: {
            limit: 10 * 1024,
            outputPath: '/imgs/'
          }
        }
      },
      {
        test: /\.css$/,
        // 不再使用style-loader，使用MiniCssExtractPlugin.loader
        loader: [MiniCssExtractPlugin.loader, "css-loader",],
      },
      {
        test: /\.less$/,
        loader: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader", "less-loader"],
      },
    ]
  },
  plugins: [
    new CleanWebpackPlugin(), // 打包之前，清空上一次残留
    new MiniCssExtractPlugin({
      filename: "css/main.[contentHash:8].css"
    }),
    // 忽略 moment 下的 /locale 目录
    new webpack.IgnorePlugin(/\.\/locale/, /moment/),
    // happyPack 开启多进程打包
    new HappyPack({
      // 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
      id: 'babel',
      // 如何处理 .js 文件，用法和 Loader 配置中一样
      loaders: ['babel-loader?cacheDirectory']
    }),
    // 使用 ParallelUglifyPlugin 并行压缩输出的 JS 代码
    new ParallelUglifyPlugin({
      // uglifyJS 是webapck内置压缩js的工具
      // 传递给 UglifyJS 的参数
      // （还是使用 UglifyJS 压缩，只不过帮助开启了多进程）
      uglifyJS: {
        output: {
          beautify: false, // 最紧凑的输出
          comments: false, // 删除所有的注释
          // .... 
        },
        compress: {
          // 删除所有的 `console` 语句，可以兼容ie浏览器
          drop_console: true,
          // 内嵌定义了但是只用到一次的变量
          collapse_vars: true,
          // 提取出出现多次但是没有定义成变量去引用的静态值
          reduce_vars: true,
          // ...
        }
      }
    })
  ],
  // 优化的
  optimization: {
    // 压缩
    minimizer: [
      // 压缩js
      new TerserJSPlugin({}),
      // 压缩css
      new OptimizeCSSAssetsPlugin({})
    ],

    // 分割代码块
    splitChunks: {
      // 不同的分法：
      //    initial   入口chunk   对于异步导入的文件不处理
      //    async  异步chunk   只对异步导入的文件处理
      //    all   全部chunk 
      chunks: "all",

      // 缓存分组
      cacheGroups: {
        // 第三方模块
        vendor: {
          name: "vendor", // chunk名称
          priority: 1, // 权限更高，优先抽离，重要！！！
          test: /node_modules/,
          minSize: 0,  // 大小限制
          minChunks: 1  // 最少复用过几次
        },
        // 公共的模块
        common: {
          name: 'common', // chunk 名称
          priority: 0, // 优先级
          minSize: 0,  // 公共模块的大小限制
          minChunks: 2  // 公共模块最少复用过几次
        }
      }
    }
  }
})

